#include "Col.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "HexFilter.h"

#include "String.h"
#include "CType.h"
#include "ET_stdio.h"

//---- HexFilter ---------------------------------------------------------------

HexFilter::HexFilter(char *et) : StreamBuf()
{
	col= 0;
	eof= FALSE;
	if (et)
		pos= endtoken= strsave(et);
	else
		pos= endtoken= 0;
}

HexFilter::~HexFilter()
{
	SafeDelete(endtoken);
}

//---- HexEncoder --------------------------------------------------------------

HexEncoder::HexEncoder(char *et) : HexFilter(et)
{
}

int HexEncoder::Overflow(u_char *bp, int n)
{
	register u_char *p= bp;
	while (n-- > 0) {
		sb->sputc(hexChars[*p / 16]);
		sb->sputc(hexChars[*p++ & 0x0f]);
		if (++col >= 40) {
			sb->sputc('\n');
			col= 0;
		}
	}
	return p-bp;
}

void HexEncoder::Close()
{
	if (endtoken)
		sb->sputn(endtoken, strlen(endtoken));
	/*
	if (col != 0)
		sb->sputc('\n');
	if (endtoken) {
		sb->sputn(endtoken, strlen(endtoken));
		sb->sputc('\n');
	}
	*/
}

//---- HexDecoder --------------------------------------------------------------

HexDecoder::HexDecoder(char *et) : HexFilter(et)
{
}

int HexDecoder::Underflow(u_char *bp, int count)
{
	register int c, i= 0;
	bool m= TRUE;
		
	if (eof)
		return EOF;

	while (i < count && (c= sb->sgetc()) != EOF) {
		int hv= HexValue(c);
		if (hv >= 0) {
			sb->stossc();
			if (m) {
				*bp= hv * 16;
				m= FALSE;
			} else {
				*bp++ += hv;
				i++;
				m= TRUE;
			}
			continue;
		}
		if (pos) {
			sb->stossc();
			if (c == *pos++) {
				if (*pos == '\0') {
					eof= TRUE;
					break;
				}
			} else
				pos= endtoken;
			continue;
		}
		if (Isspace(c)) {
			sb->stossc();
			continue;
		}
		eof= TRUE;
		break;
	}
	return i;
}

